import { Injectable } from '@angular/core';

import { QuoteBasic } from 'service/QuoteBasic';
import { IBollService } from 'interface/IBollService';

@Injectable()
export class BollService implements IBollService {

  connection;

  constructor() {

  }

  private _cacuBoll(quote:QuoteBasic, day, k, start, end) {
    let ma = 0;
    let up = 0;
    let down = 0;

    let maSum = 0;

    for(let j=start; j<=end; j++) {
      maSum+=quote.close[j];
    }

    ma = parseFloat((maSum/(end-start+1)).toFixed(4));

    let mdSum = 0;
    for(let j=start; j<=end; j++) {
      mdSum += Math.pow(quote.close[j] - ma, 2);
    }

    let md = Math.sqrt(mdSum/(end-start+1));

    up = parseFloat((ma + k*md).toFixed(4));
    down = parseFloat((ma - k*md).toFixed(4));

    return [ma, up, down];
  }

  compute(quote:QuoteBasic, day:number, k:number):Array<any> {
    const mbList = [];
    const upList = [];
    const downList = [];

    if(day>0 && k>0){
        const count = quote.close.length;
        for(let i=0; i<count; i++) {
          if(i < day) {
            const data = this._cacuBoll(quote, day, k, 0, i);
            mbList.push(data[0]);
            upList.push(data[1]);
            downList.push(data[2]);
            continue;
          }

          const data = this._cacuBoll(quote, day, k, i-day+1, i);
          mbList.push(data[0]);
          upList.push(data[1]);
          downList.push(data[2]);
        }
    }
    return [mbList, upList, downList];
  }

  update(quote:QuoteBasic, day:number, k:number, mdList:Array<any>, upList:Array<any>, downList:Array<any>):Array<any> {
    const originCount = quote.close.length;
    const oldCount = mdList.length;

    if(originCount > 0 && day > 0) {
      if(oldCount === 0){
        return this.compute(quote, day, k);
      }

      const start = (originCount - day) < 0 ? 0 : (originCount - day);
      const end = (originCount - 1) < 0 ? 0 : (originCount - 1);

      const temp = this._cacuBoll(quote, day, k, start, end);

      if (oldCount < originCount) {
        mdList.push(temp[0]);
        upList.push(temp[1]);
        downList.push(temp[2]);
      } else {
        mdList[end] = temp[0];
        upList[end] = temp[1];
        downList[end] = temp[2];
      }
    }
    return [mdList, upList, downList];
  }
}
